package org.example.java_gobang.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.java_gobang.game.MatchRequest;
import org.example.java_gobang.game.MatchResponse;
import org.example.java_gobang.game.Matcher;
import org.example.java_gobang.game.OnlineUserManager;
import org.example.java_gobang.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class MatchAPI extends TextWebSocketHandler {

    @Autowired
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private OnlineUserManager onlineUserManager = new OnlineUserManager();
    @Autowired
    private Matcher matcher;
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        try{
            User user = (User)session.getAttributes().get("user");
            //先判断当前用户是否已经处于在线状态,或已经进入对战房间,提醒用户禁止多开
            if(onlineUserManager.getFromGameRoom(user.getUserId())!=null
            || onlineUserManager.getFromGameHall(user.getUserId())!=null){
                //当前用户已经登录了.提醒禁止多开
                MatchResponse response = new MatchResponse();
                //属于正常检测到的情况,将其设为true,并返回提示信息
                response.setOk(true);
                response.setMessage("repeatConnection");
                response.setReason("当前禁止多开!");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
//                session.close();
                return;
            }
            //拿到用户的身份信息后,就把玩家设置成在线状态
            onlineUserManager.enterGameHall(user.getUserId(),session);
            System.out.println("玩家"+user.getUsername()+" 进入游戏大厅!");
        }catch(NullPointerException e){
            //未获取到用户的信息,抛出空指针异常
//            e.printStackTrace();
            System.out.println("当前用户未登录!");
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setMessage("您尚未登录,无法进行匹配!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

        //实现  开始匹配请求 和  停止匹配请求
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //1.获取当前用户信息
        User user = (User)session.getAttributes().get("user");
        //2.获取客户端给服务器发送数据
        String payload = message.getPayload();
        //当前数据为JSON格式,将其转换成java对象
        MatchRequest request = objectMapper.readValue(payload,MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if(request.getMessage().equals("startMatch")){
            //进入匹配队列:
            // 将玩家的信息放到匹配队列中:
            matcher.add(user);
            //给出响应:
            response.setOk(true);
            response.setMessage("startMatch");
        }else if(request.getMessage().equals("stopMatch")){
            //退出匹配队列:
            //将当前玩家从匹配队列中移除
            matcher.remove(user);
            //移除后,给客户端响应:
            response.setOk(true);
            response.setMessage("stopMatch");
        }else{
            //出现非法情况:
            response.setOk(false);
            response.setReason("非法的匹配请求");
        }
        //将信息返回给客户端:
        String jsonString = objectMapper.writeValueAsString(response);
        session.sendMessage(new TextMessage(jsonString));
    }
//异常断开连接
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try{
            User user = (User)session.getAttributes().get("user");
            //只有当前退出的用户是已经存的用户信息时,才退出
            //不要因多开被迫下线,导致正常的用户退出
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if(tmpSession==session){
                onlineUserManager.exitGameHall(user.getUserId());
            }
            //当玩家正在匹配中,但webSocket突然断开连接了,也需要玩家从匹配队列中异处
            matcher.remove(user);
        }catch(NullPointerException e){
            System.out.println("[MatchAPI.handleTransportError] 当前用户未登录!" );
            //此时服务器已经与客户端断开连接了,无法再发送消息了
//            e.printStackTrace();
//            System.out.println("当前用户未登录!");
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setMessage("您尚未登录,无法进行匹配!");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
//正常退出连接
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try{
            User user = (User)session.getAttributes().get("user");
            //只有当前退出的用户是已经存的用户信息时,才退出
            //不要因多开被迫下线,导致正常的用户退出
            //tmpSession是之前已经存好的信息,而session是当前正在登录的信息
            //只有当前已经存的信息就是当前要退出的人的信息才能退出成功
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if(tmpSession==session){
                onlineUserManager.exitGameHall(user.getUserId());
            }
            //当玩家正在匹配中,但webSocket突然断开连接了,也需要玩家从匹配队列中异处
            matcher.remove(user);
        }catch(NullPointerException e){
            System.out.println("[MatchAPI.afterConnectionClosed] 当前用户未登录!" );
            //此时服务器已经与客户端断开连接了,无法再发送消息了
//            e.printStackTrace();
//            System.out.println("当前用户未登录!");
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setMessage("您尚未登录,无法进行匹配!");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
}
